package com.gzc.just.play.last.war.common.net;

import com.gzc.just.play.last.war.common.serializer.MessageSerializer;
import com.gzc.just.play.last.war.common.serializer.SerializerFactory;
import static com.gzc.just.play.last.war.common.serializer.SerializerFactory.SerializerType;
import io.netty.channel.Channel;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.ByteOrder;

/**
 * 网络工具类，提供统一的消息发送接口
 * 支持不同的序列化方式（Java序列化、Protobuf等）
 */
public class NetUtils {
    private static final Logger logger = LoggerFactory.getLogger(NetUtils.class);
    private NetUtils() {}

    /**
     * 使用当前配置的序列化方式发送消息
     */
    public static void sendMsg(Channel channel, int msgId, Object netMsg) throws IOException {
        MessageSerializer serializer = SerializerFactory.getSerializer();
        sendMessage(channel, msgId, netMsg, serializer);
    }
    
    /**
     * 使用Java序列化发送消息（保留以兼容现有代码）
     */
    public static void javaSerializeAndSendMsg(Channel channel, int msgId, Object netMsg) throws IOException {
        SerializerType originalType = SerializerFactory.getCurrentSerializerType();
        SerializerFactory.setSerializerType(SerializerFactory.SerializerType.JAVA);
        MessageSerializer serializer = SerializerFactory.getSerializer();
        sendMessage(channel, msgId, netMsg, serializer);
        // 恢复原始序列化类型
        SerializerFactory.setSerializerType(originalType);
    }
    
    /**
     * 使用Protobuf序列化发送消息（保留以兼容现有代码）
     */
    public static void protobufSerializeAndSendMsg(Channel channel, int msgId, Object netMsg) throws IOException {
        SerializerType originalType = SerializerFactory.getCurrentSerializerType();
        SerializerFactory.setSerializerType(SerializerFactory.SerializerType.PROTOBUF);
        MessageSerializer serializer = SerializerFactory.getSerializer();
        sendMessage(channel, msgId, netMsg, serializer);
        // 恢复原始序列化类型
        SerializerFactory.setSerializerType(originalType);
    }
    
    /**
     * 使用指定的序列化器发送消息
     */
    private static void sendMessage(Channel channel, int msgId, Object netMsg, MessageSerializer serializer) throws IOException {
        byte[] msgData = serializer.serializeToBytes(netMsg);
        if (null == msgData) {
            logger.error("serializeToBytes return null,msgId={}", msgId);
            return;
        }

        // 创建Unity客户端兼容的消息格式：[4字节消息ID][消息体]
        // LengthFieldPrepender会自动在前面添加长度字段
        io.netty.buffer.ByteBuf buffer = io.netty.buffer.Unpooled.buffer();
        buffer.order(ByteOrder.LITTLE_ENDIAN);        
        // 写入消息ID
        buffer.writeIntLE(msgId);
        // 写入消息体
        buffer.writeBytes(msgData);

        logger.info("send msg id={},dataLen={}", msgId, msgData.length);
        // 发送消息
        channel.writeAndFlush(buffer);
    }

    // 添加消息编码和解码器，支持与Unity客户端的兼容性
    public static void addNettyCodec(ChannelPipeline pipeline) {
        pipeline.addLast("decoder", new LengthFieldBasedFrameDecoder(
                ByteOrder.LITTLE_ENDIAN, 1024 * 1024, 0, 4, 0, 4, true));
        pipeline.addLast("encoder", new LengthFieldPrepender(
                ByteOrder.LITTLE_ENDIAN, 4, 0, false));
    }

}
